package com.doge.calcalbum.business.album

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.core.content.ContextCompat.getSystemService
import com.doge.calcalbum.R
import com.doge.calcalbum.api.observeOnMain
import com.doge.calcalbum.api.subscribeOnIO
import com.doge.calcalbum.core.BaseDialogFragment
import com.doge.calcalbum.databinding.DialogFragmentAlbumEditNameBinding
import com.doge.calcalbum.db.model.Album
import com.doge.calcalbum.db.model.AlbumTitle
import com.doge.calcalbum.utils.*
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
import kotlin.math.max

class AlbumEditNameDialogFragment : BaseDialogFragment() {
    override val hasShadow = true
    private var innerBinding: DialogFragmentAlbumEditNameBinding? = null
    private val binding get() = innerBinding!!
    private val albumType by lazy { arguments?.getInt(EXTRA_ALBUM_TYPE)!! }
    private val albumId by lazy { arguments?.getInt(EXTRA_EDIT_ID) }
    private val inputHint by lazy { arguments?.getString(EXTRA_INPUT_HINT) }
    private var autoTask: Disposable? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        innerBinding =
            innerBinding ?: DialogFragmentAlbumEditNameBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.cancel.setOnClickCallback { dismissAllowingStateLoss() }
        binding.confirm.setOnClickCallback { editAlbum() }
        binding.title.setText(
            when {
                inputHint?.isNotEmpty() == true -> R.string.edit_name
                albumType == Album.TYPE_VIDEO -> R.string.create_video_album
                else -> R.string.create_album
            }
        )
        binding.message.setText(inputHint ?: "")
        binding.message.setSelection(max(0, binding.message.text.length))
        autoTask = Observable.timer(100, TimeUnit.MILLISECONDS)
            .subscribeOnIO()
            .observeOnMain()
            .doOnNext {
                binding.message.requestFocus()
                getSystemService(appContext, InputMethodManager::class.java)
                    ?.showSoftInput(binding.message, 0)
            }
            .subscribe()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        autoTask?.dispose()
        binding.cancel.setOnClickListener(null)
        binding.confirm.setOnClickListener(null)
        innerBinding = null
    }

    private fun editAlbum() {
        closeKeyBoard()
        val albumTitle = binding.message.text.toString().trim()
        if (albumTitle.isEmpty()) {
            toast(R.string.input_album_name)
            return
        }
        if (albumId.isNullOrZero()) {
            val album = Album(
                coverEntryId = null,
                title = albumTitle,
                createTime = System.currentTimeMillis(),
                count = 0,
                type = albumType
            )
            AlbumRepository.get().insert(album)
        } else {
            val edit = AlbumTitle(id = albumId!!, title = albumTitle)
            AlbumRepository.get().updateTitle(edit)
        }
        dismissAllowingStateLoss()
    }

    companion object {
        private const val EXTRA_ALBUM_TYPE = "albumType"
        private const val EXTRA_INPUT_HINT = "inputHint"
        private const val EXTRA_EDIT_ID = "editId"
        fun newInstance(
            albumType: Int,
            albumId: Int? = null,
            inputHint: String? = null
        ): AlbumEditNameDialogFragment {
            return AlbumEditNameDialogFragment().apply {
                arguments = Bundle().apply {
                    putInt(EXTRA_ALBUM_TYPE, albumType)
                    albumId?.let { putInt(EXTRA_EDIT_ID, it) }
                    inputHint?.let { putString(EXTRA_INPUT_HINT, it) }
                }
            }
        }
    }

}